package au.org.ala.phylojive

class Tree {
    User owner
    String name
    String privateUrlPath
    Boolean isPublic = true
    String tree
    String newick
    String characters
    String treebaseId
    Template presentClade
    String identifyLifeDataset
    String attribution
    Integer highlight

    static constraints = {
        name (unique: true, blank: false)
        owner (blank: false)
        privateUrlPath (nullable: true, blank: true)
        isPublic (nullable: true, blank: true)
        tree (nullable: true, widget: 'textarea')
        newick (nullable: true)
//        nexml (nullable: true, widget: 'textarea', validator: {val, obj ->
//            if( val ){
//                def df = DocumentBuilderFactory.newInstance();
//                def builder =  df.newDocumentBuilder()
//                try{
//                    // why UTF-8?
//                    builder.parse( IOUtils.toInputStream( val,'UTF-8' ) )
//                    return true;
//                } catch (Exception e ){
//                    return "NEXML is not well formed"
//                }
//
//            }
//        })
        treebaseId (nullable: true)
        characters (nullable: true, widget: 'textarea')
        presentClade (nullable: true, blank: true)
        attribution (nullable: true, widget: 'textarea')
        highlight (nullable: true, range: 1..10)
        identifyLifeDataset (nullable: true)
    }

    static mapping = {
        tree type: 'text'
//        nexml type: 'text'
        attribution type: 'text'
        presentClade type: 'text'
        characters sqlType: 'clob'
    }

    def beforeValidate() {
        System.out.println( name );
        // automcatically create a privateUrl hashcode
        if (!privateUrlPath) {
            def input = name + new Date().toString()
            privateUrlPath = input.bytes.encodeBase64().toString()
        }
        //convert newick to nexml
        if( tree && tree.matches("^[^<].+" )){
            def xml = new StringWriter()
            tree = tree.replaceAll('\n','');
            tree = tree.replaceAll(' ',"%%%%");
            def filename;
            def cmd;
            if( tree.length() > 90000 ){
                def uid = UUID.randomUUID().toString();
                filename = uid + '.newick'
                println( filename );
                def file = new File(filename);
                file.write( tree )
                def filepath = file.getAbsoluteFile();
                cmd = "perl scripts/convert.pl -file ${filepath}";
            } else {
                cmd = "perl scripts/convert.pl -string ${tree}";
            }
            println( cmd );
            def proc = cmd.execute()
            proc.waitForProcessOutput(xml , System.out)
            tree = xml.toString().replaceAll("%%%%",' ')
            if( filename ){
                "rm ${filename}".execute();
            }
//            println( "perl  scripts/convert.pl \""+ tree.replace('"',"\\\"") +"\"" );
//            def cmd = "perl scripts/convert.pl \"${tree.replace('-','_')}\"";
//            println( cmd );
//            cmd = ['sh','-c','perl', 'scripts/convert.pl',tree];
//            cmd = ['bash','-c', 'perl', 'scripts/convert.pl',tree.replace('',' ')];
//            cmd = """perl scripts/convert.pl ${tree.replace(' ','_')}"""
//            cmd = "perl scripts/convert.pl"
            println( tree.length() );
//            tree = tree.replaceAll(' ',"%%%%");
//            String[] env = new String[1];
//            env[0] = "TREE="+tree;
//            System.setProperty('TREE',tree)
//            def testproc = 'echo $TREE'.execute();

//            println(testproc.text);
//            def proc = cmd.execute()
//            println( proc.text )
//            proc.waitForProcessOutput(xml , System.out)
//            xml = xml.toString().replaceAll("%%%%",' ')
//            xml = proc.in.text;
//            println( xml );
//            String escapedTree = "\"" + tree.replace('"',"\\\"") +"\"";
//            def cmd = [ "perl", "scripts/convert.pl", escapedTree ];
//            [].execute()
//            Process perl = Runtime.getRuntime().exec( cmd );
//            System.out.println( perl. );
//            BufferedReader nexml = new BufferedReader(( new InputStreamReader(perl.getInputStream() )));
//            String s = null;
//            while((s = nexml.readLine()) != null) {
////                System.out.println( s );
//                xml += s;
//            }
//            s = nexml.readLine()
//            println( xml );
//        System.out.println( xml );
//            tree = xml;
//            println( tree )
        } else {
            if( tree.matches("^[^<].*" ) ){
                println( tree );
            }
        }
    }

    def getTreebaseUrl (){
        if( treebaseId ){
            def grailsapplication = this.getDomainClass().getGrailsApplication();
            return grailsapplication.config.treebaseUrl.replaceFirst('TREEBASEID',treebaseId);
        }
    }
}